import { render, type RenderOptions } from "@testing-library/vue";
import { createPinia } from "pinia";
import { createRouter, createWebHistory } from "vue-router";
import { expect } from "vitest";
import type { Component } from "vue";

// 创建测试路由
const createTestRouter = () => {
  return createRouter({
    history: createWebHistory(),
    routes: [
      { path: "/", component: { template: "<div>Home</div>" } },
      { path: "/test", component: { template: "<div>Test</div>" } },
    ],
  });
};

// 自定义渲染函数
export const renderWithProviders = (
  component: Component,
  options: RenderOptions<any> = {}
) => {
  const pinia = createPinia();
  const router = createTestRouter();

  return render(component, {
    global: {
      plugins: [pinia, router],
      stubs: {
        // 存根化一些复杂的组件
        "van-loading": true,
        "van-icon": true,
        "van-button": true,
        "van-field": true,
        "van-nav-bar": true,
      },
    },
    ...options,
  });
};

// 模拟API响应
export const mockApiResponse = <T>(data: T, delay = 0) => {
  return new Promise<T>((resolve) => {
    setTimeout(() => resolve(data), delay);
  });
};

// 模拟API错误
export const mockApiError = (message = "API Error", delay = 0) => {
  return new Promise((_, reject) => {
    setTimeout(() => reject(new Error(message)), delay);
  });
};

// 等待异步操作完成
export const waitFor = (ms: number) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

// 模拟用户交互
export const mockUserInteraction = {
  click: (element: HTMLElement) => {
    element.click();
  },

  input: (element: HTMLInputElement, value: string) => {
    element.value = value;
    element.dispatchEvent(new Event("input", { bubbles: true }));
  },

  submit: (form: HTMLFormElement) => {
    form.dispatchEvent(new Event("submit", { bubbles: true }));
  },
};

// 测试数据工厂
export const createTestUser = (overrides = {}) => ({
  id: 1,
  username: "testuser",
  email: "test@example.com",
  avatar_url: "/test-avatar.png",
  level: 5,
  created_at: "2024-01-01T00:00:00Z",
  updated_at: "2024-01-01T00:00:00Z",
  ...overrides,
});

export const createTestShare = (overrides = {}) => ({
  id: 1,
  user_id: 1,
  user: createTestUser(),
  title: "Test Share",
  content: "This is a test share content",
  share_type: "experience" as const,
  is_public: true,
  likes_count: 10,
  comments_count: 5,
  shares_count: 2,
  is_liked: false,
  is_bookmarked: false,
  created_at: "2024-01-01T00:00:00Z",
  updated_at: "2024-01-01T00:00:00Z",
  ...overrides,
});

export const createTestHelpRequest = (overrides = {}) => ({
  id: 1,
  user_id: 1,
  user: createTestUser(),
  title: "Test Help Request",
  description: "This is a test help request",
  category: "conversation" as const,
  status: "open" as const,
  answers_count: 3,
  views_count: 20,
  is_bookmarked: false,
  created_at: "2024-01-01T00:00:00Z",
  updated_at: "2024-01-01T00:00:00Z",
  ...overrides,
});

export const createTestTrainingSession = (overrides = {}) => ({
  id: 1,
  user_id: 1,
  character_id: 1,
  scenario_id: 1,
  status: "active" as const,
  messages: [],
  created_at: "2024-01-01T00:00:00Z",
  updated_at: "2024-01-01T00:00:00Z",
  ...overrides,
});

// 断言助手
export const expectElementToBeVisible = (element: HTMLElement | null) => {
  expect(element).toBeInTheDocument();
  expect(element).toBeVisible();
};

export const expectElementToHaveText = (
  element: HTMLElement | null,
  text: string
) => {
  expect(element).toBeInTheDocument();
  expect(element).toHaveTextContent(text);
};

export const expectElementToHaveClass = (
  element: HTMLElement | null,
  className: string
) => {
  expect(element).toBeInTheDocument();
  expect(element).toHaveClass(className);
};
